function ShaderProgram(context, shader){
	this.context = context;
	this.program = null;
	
	this.vertexPositionAttribute = null;
	this.vertexColorAttribute = null;
	this.vertexTextureAttribute = null;
	this.samplerUniform = null;
	this.pMatrixUniform = null;
	this.mvMatrixUniform = null;
	
	this.parameters = new Array();
	
	this.shader = shader?shader:null;
	
	this.setShader = function(shader){
		this.shaders.add(shader);
	}
	
	this.create = function(){
		// find shader
		var shader = this.shader;
		if(!shader)return null;
		if(this.program)return this.program;
		
		// found a shared
		// compile the shaders
		this.program = this.context.createProgram();
		if(shader.vertexScript){
			var contextShader = this.context.createShader(this.context.VERTEX_SHADER);
			
			this.context.shaderSource(contextShader, shader.vertexScript);
			
			this.context.compileShader(contextShader);
			
			if (!this.context.getShaderParameter(contextShader, this.context.COMPILE_STATUS)) {
				throw "Error compiling shader - " + this.context.getShaderInfoLog(contextShader);
			}
			this.context.attachShader(this.program, contextShader);
		}
		if(shader.fragmentScript){
			var contextShader = this.context.createShader(this.context.FRAGMENT_SHADER);
			
			this.context.shaderSource(contextShader, shader.fragmentScript);
			
			this.context.compileShader(contextShader);
			
			if (!this.context.getShaderParameter(contextShader, this.context.COMPILE_STATUS)) {
				throw "Error compiling shader - " + this.context.getShaderInfoLog(contextShader);
			}
			
			this.context.attachShader(this.program, contextShader);
		}
		this.context.linkProgram(this.program);
		if (!this.context.getProgramParameter(this.program, this.context.LINK_STATUS)) {
			throw "Error linking shader program."
			return;
		}
	}
	this.use = function(options){
		if(!this.program) this.program = this.create();
		
		// resolve shader program properties from shader
		// use static for now
		this.vertexPositionAttribute = this.context.getAttribLocation(this.program, "aVertexPosition");
		this.context.enableVertexAttribArray(this.program.vertexPositionAttribute);
		
		if(!options || options.useColors){
			this.vertexColorAttribute = this.context.getAttribLocation(this.program, "aVertexColor");
			this.context.enableVertexAttribArray(this.program.vertexColorAttribute);
		}
		if(!options || options.useTexture){
			this.vertexTextureAttribute = this.context.getAttribLocation(this.program, "aTextureCoord");
			this.context.enableVertexAttribArray(this.program.vertexTextureAttribute);
		}
		
		this.pMatrixUniform = this.context.getUniformLocation(this.program, "uPMatrix");
		this.mvMatrixUniform = this.context.getUniformLocation(this.program, "uMVMatrix");
		this.samplerUniform = this.context.getUniformLocation(this.program, "uSampler");
		/*
		for(var i=0;i<this.shader.parameters.length;i++){
			var param = this.shader.parameters[i];
			if(param.type=="attribute"){
				this.program[param.name] = this.context.getAttribLocation(this.program, param.name);
			}
			if(param.type=="uniform"){
				this.program[param.name] = this.context.getUniformLocation(this.shaderProgram, param.name);
			}
		}*/
		
		this.context.useProgram(this.program);
	}
}

function ShadersRepo(){
	this.shadersRepo = new Array();
	this.shadersRepo.push(new CustomShader("DrawingShader"
	,"attribute vec3 aVertexPosition;attribute vec4 aVertexColor;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying vec4 vColor;void main(void) {gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.5);vColor = aVertexColor;}",
	"precision mediump float;varying vec4 vColor;void main(void) {gl_FragColor = vColor;}",
	[
		new CustomShaderParameter("aVertexPosition","attribute"),
		new CustomShaderParameter("aVertexColor","attribute"),
		new CustomShaderParameter("uPMatrix","uniform"),
		new CustomShaderParameter("uMVMatrix","uniform"),
	]));
	
	this.findShader = function(name){
		for(var i=0;i<this.shadersRepo.length;i++){
			if(this.shadersRepo[i].name==name){
				return this.shadersRepo[i];
			}
		}
		return null;
	}
}

function CustomShaderParameter(scriptName, type){
	this.type = type;
	this.scriptName = scriptName;
	//this.programName = programName;
}
function CustomShader(name,vertexShaderScript, fragmentShaderScript, properties){
	this.name = name;
	this.vertexScript = vertexShaderScript;
	this.fragmentScript = fragmentShaderScript;
	
	this.properties = properties;
}